///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _BUOLA_IMAGE_CANYVIEW_H_
#define _BUOLA_IMAGE_CANYVIEW_H_

#include <buola/image/ccolor.h>
#include <buola/image/format.h>

namespace buola { namespace img {

class CAnyView
{
public:
    CAnyView()
        :   mData(nullptr)
        ,   mFormat(FORMAT_INVALID)
        ,   mSize(0,0)
    {}

    template<typename tFmt>
    CAnyView(const CView<tFmt> &pRH)
        :   mData(const_cast<uint8_t*>(pRH.RawBytes()))
        ,   mFormat(tFmt::mID)
        ,   mSize(pRH.Size())
        ,   mStride(pRH.Stride())
    {}

    CAnyView(const CAnyView&)=default;
    CAnyView &operator=(const CAnyView&)=default;

    EImageFormat Format() const     {   return mFormat;     }
    const CSize_i &Size() const    {   return mSize;       }
    int Width() const                           {   return mSize.x; }
    int Height() const                          {   return mSize.y; }
    ptrdiff_t Stride() const        {   return mStride;     }

    const uint8_t *RawBytes() const                     {   return mData;                       }
    const uint8_t *RawBytes(int pRow) const             {   return mData+pRow*mStride;          }

    template<typename tFmt>
    CAnyView &operator=(const CView<tFmt> &pRH)
    {
        mData=const_cast<uint8_t*>(pRH.RawBytes());
        mFormat=tFmt::mID;
        mSize=pRH.Size();
        mStride=pRH.Stride();
        return *this;
    }

    template<typename tFmt>
    CView<tFmt> View() const
    {
        if(tFmt::mID!=mFormat)
            throw XInvalid("wrong format in CAnyView::View");

        return {(typename CView<tFmt>::TPointer)mData,mSize,mStride};
    }

    template<typename tFmt>
    CMView<tFmt> MView() const
    {
        if(tFmt::mID!=mFormat)
            throw XInvalid("wrong format in CAnyView::MView");

        return {(typename CMView<tFmt>::TPointer)mData,mSize,mStride};
    }

private:
    uint8_t *mData;
    EImageFormat mFormat;
    CSize_i mSize;
    ptrdiff_t mStride;
};

/*namespace img*/ } /*namespace buola*/ }

#endif
